﻿using System;
using System.Collections.Generic;
using System.Linq;
using MWS.Processing.Interfaces;

namespace MWS.Processing.Processors
{

    public abstract class 
        RequestTrackedProcessor<TRequest, TResponse> :
        OperationProcessor<TRequest, TResponse> 
        where TRequest : class
    {
        private readonly IRequestTracker requestTracker;

        protected RequestTrackedProcessor(
            Func<TRequest, TResponse> operation,
            IRequestTracker requestTracker) : base(operation)
        {
            this.requestTracker = requestTracker;
        }

        public override IList<TRequest> GetRequests(int maxRequests)
        {
            var requestFilter = requestTracker.GetRequests(requestTracker.TrackingWindow)
                .Select(r => r.Key)
                .ToList();
            var requests = GetRequests(maxRequests, requestFilter);
            var requestKeys = requests.ToList().Select(GetRequestKey).ToList();
            if (requestKeys.Count > 0)
                requestTracker.RecordRequests(requestKeys);
            return requests;
        }

        public abstract IList<TRequest> GetRequests(int maxRequests, IList<string> requestFilter);

        public abstract String GetRequestKey(TRequest request);
    }


    public abstract class 
        TimeTrackedProcessor<TRequest, TResponse> : 
        OperationProcessor<TRequest, TResponse>
        where TRequest : class
    {
        public TimeSpan TrackingWindow { get; set; }

        protected TimeTrackedProcessor(
            Func<TRequest, TResponse> operation,
            TimeSpan trackingWindow) : base(operation)
        {
            TrackingWindow = trackingWindow;
        }

        public override IList<TRequest> GetRequests(int maxRequests)
        {
            var timeFilter = DateTime.UtcNow.Subtract(TrackingWindow);
            return GetRequests(maxRequests, timeFilter);
        }

        public abstract IList<TRequest> GetRequests(int maxResults, DateTime timeFilter);
    }
}